package jmine.tec.hydra.services.buscar;

import static jmine.tec.services.api.ActionsEnum.BUSCAR;

import java.util.List;

import jmine.tec.di.annotation.Injected;
import jmine.tec.hydra.HydraMessages;
import jmine.tec.hydra.dao.HydraRequestDAO;
import jmine.tec.hydra.domain.HydraRequestImpl;
import jmine.tec.hydra.domain.HydraSystem;
import jmine.tec.hydra.domain.enumx.HydraRequestType;
import jmine.tec.services.annotations.Execution;
import jmine.tec.services.annotations.Input;
import jmine.tec.services.annotations.Output;
import jmine.tec.services.annotations.ServiceImplementor;
import jmine.tec.services.api.ServiceExecutionException;
import bancosys.tec.utils.date.Timestamp;

/**
 * Serviço que busca uma {@link HydraRequestImpl} através dos parâmetros informados.
 * 
 * @author finx
 * @created Jun 6, 2012
 */
@ServiceImplementor(action = BUSCAR)
public class HydraRequestService {

    public static final String IDENTIFICADOR = "Identificador";

    public static final String TIMESTAMP = "Data/hora";

    public static final String REQUEST_TYPE = "Tipo";

    public static final String SYSTEM = "Sistema";

    private Timestamp timeStamp;

    private HydraRequestType requestType;

    private HydraSystem system;

    private HydraRequestDAO dao;

    /**
     * Executa o serviço.
     * 
     * @return {@link HydraRequestImpl} encontrado.
     * @throws ServiceExecutionException caso ocorra algum erro durante a execução do serviço.
     */
    @Execution
    @Output(propertyName = IDENTIFICADOR)
    public HydraRequestImpl execute() throws ServiceExecutionException {
        List<HydraRequestImpl> requests = this.dao.findByPeriodoTipoSistema(this.timeStamp, this.timeStamp, this.requestType, this.system);
        if (requests.isEmpty()) {
            throw new ServiceExecutionException(HydraMessages.REQUEST_NOT_FOUND.create(this.timeStamp, this.requestType, this.system));
        }
        if (requests.size() > 1) {
            throw new ServiceExecutionException(HydraMessages.TOO_MANY_REQUESTS.create(requests.size(), this.timeStamp, this.requestType,
                    this.system));
        }
        return requests.get(0);
    }

    /**
     * @param timeStamp the timeStamp to set
     */
    @Input(fieldName = TIMESTAMP)
    public void setTimeStamp(Timestamp timeStamp) {
        this.timeStamp = timeStamp;
    }

    /**
     * @param requestType the requestType to set
     */
    @Input(fieldName = REQUEST_TYPE)
    public void setRequestType(HydraRequestType requestType) {
        this.requestType = requestType;
    }

    /**
     * @param system the system to set
     */
    @Input(fieldName = SYSTEM)
    public void setSystem(HydraSystem system) {
        this.system = system;
    }

    /**
     * @param dao the dao to set
     */
    @Injected
    public void setDao(HydraRequestDAO dao) {
        this.dao = dao;
    }

}
